package br.org.etec.dotcao.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.map.annotate.JsonDeserialize;

import br.org.etec.dotcao.utils.json.CustomDateSerializer;

@NamedQueries({@NamedQuery(name="selectAuth", query="select u from User u where u.username = :username and u.password = :password"),
	           @NamedQuery(name="selectOauth", query="select u from User u where u.oauthInfo.code = :oauth"),
	           @NamedQuery(name="selectEmail", query="select u from User u where u.username = :username")})
@Table(name="tuser")
@Entity
public class User extends AbstractEntity{

	private static final long serialVersionUID = 1L;

	@Column(unique=true)
	@NotNull
	private String username;

	@Column
	@NotNull
	private String password;

	@Column
	private String firstname;

	@Column
	private String lastname;

	@Column
	private String gender;

	@JsonDeserialize(using=CustomDateSerializer.class)
	@Temporal(TemporalType.DATE)
	private Date birthday;

	@ManyToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="address")
	private Address address;

	@JsonIgnore
	@OneToMany(cascade=CascadeType.ALL, mappedBy = "sender")
	private List<Message> sent;

	@JsonIgnore
	@OneToMany(cascade=CascadeType.ALL, mappedBy = "receiver")
	private List<Message> received;
	
	@OneToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="picture")
	private UserPicture picture;

	@JsonIgnore
	@OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="owner")
	private List<Animal> animals;
	
	@OneToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="oauthinfo")
	private OauthInfo oauthInfo;
	
	public List<Animal> getAnimals() {
		if(animals == null){
			animals = new ArrayList<Animal>();
		}
		
		return animals;
	}
	
	public void setAnimals(List<Animal> animals) {
		this.animals = animals;
	}
	
	public void addAnimal(Animal animal){
		if(animal == null){
			return;
		}
		
		animal.setOwner(this);
		getAnimals().add(animal);
	}
	
	public OauthInfo getOauthInfo() {
		return oauthInfo;
	}
	
	public void setOauthInfo(OauthInfo oauthInfo) {
		this.oauthInfo = oauthInfo;
	}
	
	public UserPicture getPicture() {
		return picture;
	}
	
	public void setPicture(UserPicture picture) {
		this.picture = picture;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getFirstname() {
		return firstname;
	}

	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}

	public String getLastname() {
		return lastname;
	}

	public void setLastname(String lastname) {
		this.lastname = lastname;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	public List<Message> getSent() {
		return sent;
	}

	public void setSent(List<Message> sent) {
		this.sent = sent;
	}

	public List<Message> getReceived() {
		return received;
	}

	public void setReceived(List<Message> received) {
		this.received = received;
	}

	public boolean authenticate() {
		return false;
	}
}
